package com.dayu.finecomm.dsc.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayu.finecomm.dsc.DSCInterface;
import com.dayu.finecomm.dsc.DTUProxyManager;
import com.dayu.finecomm.dsc.net.DSCNetManager;
import com.dayu.finecomm.dsc.protocol.DDP;
import com.dayu.finecomm.dsc.protocol.DDP.DDPPack;
import com.dayu.finecomm.utils.Helpers;

/**
 * 处理来自UDP的消息
 * 
 * @author hddz
 * @since 2017-07-27 15:48:20
 * @version V1.0
 */
public class DSCUdpHandler extends DSCHandler<DatagramPacket> {

	static Logger LOGGER = LoggerFactory.getLogger(DSCUdpHandler.class);

	/**
	 * DDP协议解析器
	 */
	private DDP mDDP = null;

	public DSCUdpHandler(DSCInterface callback) {
		mDDP = new DDP();
		mCallback = callback;
	}

	/**
	 * UDP接收通道生效调用
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// super.channelActive(ctx);

		if (null != mCallback) {
			mCallback.initChannel(ctx);
		}
	}

	/**
	 * 处理接收消息
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg)
			throws Exception {
		ByteBuf buf = msg.copy().content();
		byte[] data = new byte[buf.readableBytes()];
		buf.readBytes(data);

		LOGGER.info("receive:" + Helpers.bytesToHex(data));

		String socket = getRemoteAddress(msg);
		DDPPack pack = mDDP.unpack(data);

		DDPPack ackPack = DTUProxyManager.getInstance().processDDP(socket,
				ctx.channel(), DSCNetManager.DSC_NET_UDP, pack);

		if (null != ackPack) {
			byte[] byteAck = mDDP.pack(ackPack, DDP.DDP_UDP);
			DatagramPacket rawData = new DatagramPacket(
					Unpooled.copiedBuffer(byteAck), msg.sender());
			ctx.writeAndFlush(rawData);

			if (null != pack && DDP.DTU_PACK_TYPE_REG == pack.getType()) {
				ctx.fireChannelActive();
			}
		} else {
			if (DDP.DTU_PACK_TYPE_SEND_DATA == pack.getType()) {
				// ByteBuf userBuf = Unpooled.buffer(data.length);
				// userBuf.writeBytes(data);
				ctx.fireChannelRead(msg);
			}
		}
	}
}
